package com.qfxl.common.comm.mybatis;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.util.ObjectUtils;

import javax.persistence.Column;
import javax.persistence.Table;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * SQL提供者类
 */
public class BaseSqlProvider<T> {

    String tableName;

    public BaseSqlProvider() {

    }

    private String getTableName(Class<?> clazz) {
        Table tableAnnotation = clazz.getAnnotation(Table.class);
        if (tableAnnotation != null && !tableAnnotation.name().isEmpty()) {
            return tableAnnotation.name();
        }
        return clazz.getSimpleName(); // 默认使用类名作为表名
    }

    /**
     * 从 QueryWrapper 中提取实体类信息。
     * 这里假设 QueryWrapper 提供了一种机制来访问其处理的实体类。
     */
    private Class<?> extractEntityClass(QueryWrapper<?> query) {
        // 假设 QueryWrapper 有一个方法可以返回处理的实体类
        // 实际实现可能需要根据你的 QueryWrapper 定义调整
        return query.getEntityClass();
    }

    public String insert(T entity) {
        return new SQL() {{
            INSERT_INTO(getTableName(entity.getClass()));
            for (Field field : entity.getClass().getDeclaredFields()) {
                String column = getColumnName(field);
                String fieldName = field.getName();
                field.setAccessible(true);
                try {
                    Column annotation = field.getAnnotation(Column.class);
                    if (!ObjectUtils.isEmpty(annotation)) {
                        String name = annotation.name();
                        if (field.get(entity) != null) {
                            VALUES(name, "#{" + fieldName + "}");
                        }
                    }
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }}.toString();
    }

    public String deleteById(@Param("id") Object id) {
        return new SQL() {{
            DELETE_FROM(tableName);
            WHERE("id = #{id}");
        }}.toString();
    }

    public String deleteByQuery(@Param("query") QueryWrapper<T> query) {
        String sql = new SQL() {{
            DELETE_FROM(tableName);
        }}.toString();

        return sql + query.buildSql();
    }

    public String updateById(T entity) {
        SQL sql = new SQL() {{
            UPDATE(getTableName(entity.getClass()));
            for (Field field : entity.getClass().getDeclaredFields()) {
//                String column = getColumnName(field);
                Column annotation = field.getAnnotation(Column.class);
                if (!ObjectUtils.isEmpty(annotation)){
                    String fieldName = field.getName();
                    field.setAccessible(true);
                    try {
                        String column = annotation.name();
                        if (field.get(entity) != null && !"id".equals(fieldName)) {
                            SET(column + " = #{" + fieldName + "}");
                        }
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            WHERE("id = #{id}");
        }};
        return sql.toString();
    }

    public String updateByQuery(@Param("entity") T entity, @Param("query") QueryWrapper<T> query) {
        SQL sql = new SQL() {{
            UPDATE(getTableName(entity.getClass()));
            for (Field field : entity.getClass().getDeclaredFields()) {
                String column = getColumnName(field);
                String fieldName = field.getName();
                field.setAccessible(true);
                try {
                    if (field.get(entity) != null && !"id".equals(fieldName)) {
                        SET(column + " = #{entity." + fieldName + "}");
                    }
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            }
        }};

        return sql.toString() + query.buildSql();
    }

    public String selectById(@Param("id") Object id) {
        return new SQL() {{
            SELECT("*");
            FROM(tableName);
            WHERE("id = #{id}");
        }}.toString();
    }

    public String selectAll() {
        return new SQL() {{
            SELECT("*");
            FROM(tableName);
        }}.toString();
    }

    public String selectByQuery(@Param("query") QueryWrapper<T> query) {
        String sql = new SQL() {{
            SELECT("*");
            FROM(getTableName(query.getEntityClass()));
        }}.toString();
        String s = sql + query.buildSql();
        System.out.println("sql--:" + s);
        return s;
    }

    public String countByQuery(@Param("query") QueryWrapper<T> query) {
        String sql = new SQL() {{
            SELECT("COUNT(1)");
            FROM(tableName);
        }}.toString();

        return sql + query.buildSql();
    }

    public String selectPage(@Param("query") QueryWrapper<T> query,
                             @Param("pageNum") int pageNum,
                             @Param("pageSize") int pageSize
    ) {
        String sql = new SQL() {{
            SELECT("*");
            FROM(tableName);
        }}.toString();

        sql += query.buildSql();
        sql += " LIMIT #{pageSize} OFFSET #{pageNum * pageSize}";
        return sql;
    }


    private String getColumnName(Field field) {
        // 这里可以通过注解获取列名，或者简单处理使用字段名转下划线
        return camelToUnderline(field.getName());
    }

    private String camelToUnderline(String camel) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < camel.length(); i++) {
            char c = camel.charAt(i);
            if (Character.isUpperCase(c)) {
                result.append("_").append(Character.toLowerCase(c));
            } else {
                result.append(c);
            }
        }
        return result.toString();
    }

    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        map.put("userName", "null");
        System.out.println(map.get("userName") == null);
    }
}